package com.tcfvic.client.panels.widgets;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.tcfvic.client.PersonService;
import com.tcfvic.client.PersonServiceAsync;
import com.tcfvic.client.panels.widgets.addons.advancedtable.AdvancedTable;
import com.tcfvic.client.panels.widgets.addons.advancedtable.RowSelectionListener;
import com.tcfvic.client.pojos.Fundingsource;

public class FundingSourceDetailsInputWidget extends FlexTable implements
		RowSelectionListener {
	private TextBox fundingSourceId = new TextBox();
	private TextBox sourceNameTB = new TextBox();
	private TextBox deliveredViaTB = new TextBox();
	private TextBox contactPeopleTB = new TextBox();
	private TextBox hoursTB = new TextBox();
	private TextBox daysTB = new TextBox();
	private TextBox fundingAmountTB = new TextBox();
	private TextArea notesTB = new TextArea();
	private TextBox contactPosition = new TextBox();
	private TextBox tel1 = new TextBox();
	private TextBox tel2 = new TextBox();
	private TextBox email = new TextBox();
	private FundingSourceDetailsListWidget list = null;

	/**
	 * Create a remote service proxy to talk to the server-side funding source
	 * Details service.
	 */
	private final PersonServiceAsync personService = GWT
			.create(PersonService.class);

	public FundingSourceDetailsInputWidget() {
		super();

		// Create a table to layout the form options
		setCellSpacing(4);
		setWidth("100%");

		// Add some standard form options
		int rowNum = 0;
		setHTML(rowNum, 0, "Funding source name");
		setWidget(rowNum, 1, sourceNameTB);
		setHTML(rowNum, 2, "Contact");
		setWidget(rowNum++, 3, contactPeopleTB);
		setHTML(rowNum, 0, "Delivered via");
		setWidget(rowNum, 1, deliveredViaTB);
		setHTML(rowNum, 2, "Contact position");
		setWidget(rowNum++, 3, contactPosition);
		setHTML(rowNum, 0, "Initial funding amount");
		setWidget(rowNum, 1, fundingAmountTB);
		setHTML(rowNum, 2, "Contact phone");
		setWidget(rowNum++, 3, tel1);
		setHTML(rowNum, 0, "Hours allowed (if applicable)");
		setWidget(rowNum, 1, hoursTB);
		setHTML(rowNum, 2, "Contact mobile");
		setWidget(rowNum++, 3, tel2);
		setHTML(rowNum, 0, "Days allowed (if applicable)");
		setWidget(rowNum, 1, daysTB);
		setHTML(rowNum, 2, "Contact email");
		setWidget(rowNum++, 3, email);
		setHTML(rowNum, 0, "Notes");
		setWidget(rowNum++, 1, notesTB);

		final Button saveButton = new Button("Save");
		saveButton.getElement().setId("saveButton");
		setWidget(5, 3, saveButton);

		// Add a handler to close the DialogBox
		saveButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				saveFundingSourceDetails();
			}
		});

		clearAllFields();
	}

	public void addFundingSourceDetailsList(FundingSourceDetailsListWidget list) {
		this.list = list;
	}

	private boolean validInput() {
		if (fundingSourceId.getText() != null
				&& fundingSourceId.getText().trim().equals("-1")) {
			Integer.parseInt(fundingSourceId.getText());
			new SimpleMessagePopup(
					"Please select a funding source before trying to edit details " +
					"or click Create new",
					
					null).showPopup();
			return false;
		}
		try {

			if (fundingAmountTB.getText() != null
					&& fundingAmountTB.getText().trim().length() > 0) {
				Double.parseDouble(fundingAmountTB.getText());
			}
		} catch (Exception e) {
			new SimpleMessagePopup(
					"The amount you supplied in the text initial funding " +
					"amount isn't a valid number",
					fundingAmountTB).showPopup();
			return false;
		}
		return true;
	}

	private boolean minimumInput() {
		if (sourceNameTB.getText() == null
				|| sourceNameTB.getText().trim().length() == 0) {
			new SimpleMessagePopup("Please enter a funding source name",
					sourceNameTB).showPopup();
			return false;
		}
		return true;
	}

	public void createNewRecord() {
		clearAllFields();
		fundingSourceId.setText("");
	}

	public void clearAllFields() {
		fundingSourceId.setText("-1");
		sourceNameTB.setText("");
		deliveredViaTB.setText("");
		contactPeopleTB.setText("");
		hoursTB.setText("");
		daysTB.setText("");
		fundingAmountTB.setText("");
		contactPosition.setText("");
		tel1.setText("");
		tel2.setText("");
		email.setText("");
		notesTB.setText("");
	}

	@Override
	public void onRowSelected(AdvancedTable sender, String rowId) {
		clearAllFields();
		personService.getFundingSourceDetails(Integer.valueOf(rowId),
				new AsyncCallback<Fundingsource>() {
					@Override
					public void onSuccess(Fundingsource result) {
						fundingSourceId.setText(String.valueOf(result.getId()));
						sourceNameTB.setText(result.getSourceName());
						deliveredViaTB.setText(result.getDeliveredvia());
						contactPeopleTB.setText(result.getContactpeople());
						notesTB.setText(result.getNotes());
						contactPosition.setText(result.getContactposition());
						tel1.setText(result.getTel1());
						tel2.setText(result.getTel2());
						email.setText(result.getEmail());
						if (result.getHours() != null) {
							hoursTB.setText(result.getHours().toString());
						}
						if (result.getDays() != null) {
							daysTB.setText(result.getDays().toString());
						}
						if (result.getInitialamount() != null) {
							fundingAmountTB.setText(String.valueOf(result
									.getInitialamount()));
						}
					}

					@Override
					public void onFailure(Throwable caught) {
						System.err
								.println("Error occured returning the funding source details: "
										+ caught);
						new SimpleMessagePopup(
								"The funding source record was not retrieved due to an internal error",
								null).showPopup();
					}
				});
	}

	private void saveFundingSourceDetails() {
		try {
			if (!validInput() || !minimumInput()) {
				return;
			}

			Fundingsource fs = new Fundingsource();
			if (fundingSourceId.getText().trim().length() > 0) {
				fs.setId(new Integer(fundingSourceId.getText()));
			}

			fs.setSourceName(sourceNameTB.getText());
			fs.setDeliveredvia(deliveredViaTB.getText());
			fs.setContactpeople(contactPeopleTB.getText());
			fs.setNotes(notesTB.getText());
			fs.setContactposition(contactPosition.getText());
			fs.setTel1(tel1.getText());
			fs.setTel2(tel2.getText());
			fs.setEmail(email.getText());
			try {
				fs.setInitialamount(Double.valueOf(fundingAmountTB.getText()));
			} catch (Exception e) {
			}
			try {
				fs.setHours(Long.valueOf(hoursTB.getText()));
			} catch (Exception e) {
			}
			try {
				fs.setDays(Long.valueOf(daysTB.getText()));
			} catch (Exception e) {
			}

			personService.saveFundingSourceDetails(fs,
					new AsyncCallback<Void>() {
						@Override
						public void onSuccess(Void result) {
							clearAllFields();
							if (list != null) {
								list.updateTableData();
							}
							new SimpleMessagePopup(
									"Funding source saved successfully", null)
									.showPopup();
						}

						@Override
						public void onFailure(Throwable caught) {
							System.err
									.println("Error occured writing funding source details to database in "
											+ "FundingSourceDetailsInputWidget.saveFundingSourceDetail: "
											+ caught);
							new SimpleMessagePopup(
									"The data was not saved due to an internal error",
									null).showPopup();
						}
					});
		} catch (Exception e) {
			new SimpleMessagePopup(
					"An error occured saving the funding source details: " + e,
					null).showPopup();
		}
	}

}
